package com.zhang.handler;

import com.zhang.ChannelManage;
import com.zhang.common.Constant;
import com.zhang.common.message.ProxyMessage;
import com.zhang.common.message.ProxyMessageUtil;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.timeout.IdleStateEvent;
import io.netty.util.ReferenceCountUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 收到心跳
 * @author 98265
 */
public class HeartDataHandler extends ChannelInboundHandlerAdapter {

    /**
     * 日志对象
     */
    static private Logger log = LoggerFactory.getLogger(HeartDataHandler.class);
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        ProxyMessage proxyMessage = (ProxyMessage) msg;
        Byte msgType = proxyMessage.getMsgType();
        //处理心跳包
        if(msgType == Constant.HeartBeat.TYPE_HEART_BEAT_RESPONSE){
            log.debug("收到代理服务端心跳包");
            ReferenceCountUtil.release(msg);
        }else{
            ctx.fireChannelRead(msg);
        }

    }

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
            if(evt instanceof IdleStateEvent){
                IdleStateEvent idleStateEvent = (IdleStateEvent) evt;
                switch (idleStateEvent.state()) {
                    case READER_IDLE:
                        log.debug("读超时 发送心跳包");
                        sendHeartMsg(ctx);
                        break;
                    case WRITER_IDLE:
                        log.debug("写超时 发送心跳包");
                        sendHeartMsg(ctx);
                        break;
                    case ALL_IDLE:
                        log.debug("所有都超时 发送心跳包");
                        sendHeartMsg(ctx);
                        break;
                }
            }
    }

    private void sendHeartMsg(ChannelHandlerContext ctx) {
        ProxyMessage proxyMessage = ProxyMessageUtil.buildHeartBeatResp();
        ctx.writeAndFlush(proxyMessage);
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        //这里的客户端 指的是代理客户端
        log.debug("代理客户端通道激活");
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        log.debug("代理客户端离线");
        //从map中通过域名移除channel
        closeChannel(ctx);
    }

    /**
     * 移除map  关闭连接
     * @param ctx
     */
    private void closeChannel(ChannelHandlerContext ctx) {
        ChannelManage.setNgrokServerChannel(null);
        //断开连接
        ctx.close();
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        log.debug("代理客户端异常{}",cause);
        //从map中通过域名移除channel
        closeChannel(ctx);
    }
}
